<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Layout management in JavaScript GTK</title>
<link rel="stylesheet" href="/cfg/format.css" type="text/css">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<meta name="keywords" content="Layout management, GTK, JavaScript, programming, tutorial, Linux">
<meta name="description" content="This part of the JavaScript GTK tutorial covers layout management.">
<meta name="language" content="en">
<meta name="author" content="Jan Bodnar">
<meta name="distribution" content="global">

<script type="text/javascript" src="/lib/jquery.js"></script>
<script type="text/javascript" src="/lib/common.js"></script>

</head>

<body>

<div class="container">

<div id="wide_ad" class="ltow">
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* 160x600, August 2011 */
google_ad_slot = "2484182563";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<div class="content">


<a href="/" title="Home">Home</a>&nbsp;
<a href=".." title="Home">Contents</a>


<h1>Layout management</h1>


<p>
In this chapter we will show how to lay out our widgets in windows or dialogs. 
</p>

<div class="center">
<script type="text/javascript"><!--
google_ad_client = "ca-pub-9706709751191532";
/* top_horizontal */
google_ad_slot = "3327173442";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>

<p>
When we design the GUI of our application, we decide what widgets we will use and 
how we will organize those widgets in the application. To organize our widgets, 
we use specialized non visible widgets called <b>layout containers</b>. In this chapter, 
we will mention <b>Alignment</b>, <b>Fixed</b>, <b>VBox</b> and <b>Table</b>.
</p>


<h2>Fixed</h2>

<p>
The <b>Fixed</b> container places child widgets at fixed positions and with fixed sizes.
This container performs no automatic layout management. In most applications, we don't use 
this container. There are some specialized areas, where we use it.
For example games, specialized applications that work with diagrams, resizable components
that can be moved (like a chart in a spreadsheet application), small educational examples.
</p>


<pre class="code">
#!/usr/bin/seed

/*
ZetCode JavaScript GTK tutorial

In this program, we lay out widgets
using absolute positioning

author: Jan Bodnar
website: www.zetcode.com
last modified: July 2011
*/

Gtk = imports.gi.Gtk;
Gdk = imports.gi.Gdk;


Gtk.init(null, null);

Example = new GType({
    parent: Gtk.Window.type,
    name: "Example",
    init: function ()
    {

        init_ui(this);
        
        function init_ui(w) {
          
            w.signal.hide.connect(Gtk.main_quit);
            w.set_default_size(300, 280);
            w.set_title("Fixed");
            w.set_position(Gtk.WindowPosition.CENTER);

            w.modify_bg(Gtk.StateType.NORMAL, 
                new Gdk.Color({red:6400, green:6400, blue:6440}));
            
            var image1 = new Gtk.Image.from_file("bardejov.jpg");
            var image2 = new Gtk.Image.from_file("rotunda.jpg");
            var image3 = new Gtk.Image.from_file("mincol.jpg");

            var fixed = new Gtk.Fixed();
            
            fixed.put(image1, 20, 20);
            fixed.put(image2, 40, 160);
            fixed.put(image3, 170, 50);
            
            w.add(fixed);
            w.show_all();                     
        }
    }       
});


var window = new Example();
Gtk.main();
</pre>

<p>
In our example, we show three small images on the window. 
We explicitly specify the x, y coordinates, where we place these images. 
</p>

<pre class="explanation">
w.modify_bg(Gtk.StateType.NORMAL, 
    new Gdk.Color({red:6400, green:6400, blue:6440}));
</pre>

<p>
For better visual experience, we change the background color to dark gray. 
</p>

<pre class="explanation">
var image1 = new Gtk.Image.from_file("bardejov.jpg");
</pre>

<p>
The <b>Image</b> is a widget, that is used to display
images. The picture is loaded from the file on the disk.
</p>

<pre class="explanation">
var fixed = new Gtk.Fixed();
</pre>

<p>
We create the <b>Fixed</b> container. 
</p>

<pre class="explanation">
fixed.put(image1, 20, 20);
</pre>

<p>
 We place the first image at x=20, y=20 coordinates. 
</p>

<pre class="explanation">
w.add(fixed);
</pre>

<p>
Finally, we add the <b>Fixed</b> container to the Window. 
</p>

<img src="/img/gui/jsgtk/fixed.png" alt="Fixed">
<div class="figure">Figure: Fixed</div>


<h2>Buttons</h2>

<p>
In this code example, we will use a vertical box, a horizontal box and an alignment
widget. A horizontal box arranges widgets in a single row. Similarly, a vertical box
places its widgets in one column. 
The <b>Alignment</b> container controls the alignment and the size of its child widget. 
</p>

<pre class="code">
#!/usr/bin/seed

/*
ZetCode JavaScript GTK tutorial

In this program, we position two buttons
in the bottom right corner of the window.
We use horizontal and vertical boxes.

author: Jan Bodnar
website: www.zetcode.com
last modified: July 2011
*/

Gtk = imports.gi.Gtk;

Gtk.init(null, null);

Example = new GType({
    parent: Gtk.Window.type,
    name: "Example",
    init: function ()
    {
        
        init_ui(this);
        
        function init_ui(w) {
      
            w.signal.hide.connect(Gtk.main_quit);
            w.set_default_size(260, 150);
            w.set_title("Buttons");
            w.set_position(Gtk.WindowPosition.CENTER);

            var vbox = new Gtk.VBox({homogeneous: false, spacing:5});
            var hbox = new Gtk.HBox({homogeneous: true, spacing:3});

            var space = new Gtk.Frame();
            vbox.pack_start(space, true, true, 0);
            
            var okButton = new Gtk.Button({label:"OK"});
            okButton.set_size_request(70, 30);
            var closeButton = new Gtk.Button({label:"Close"});
            
            hbox.add(okButton);
            hbox.add(closeButton);
            
            var halign = new Gtk.Alignment({xalign: 1.0, yalign: 0.0, 
                                           xscale: 0.0, yscale: 0.0});
            halign.add(hbox);
            vbox.pack_start(halign, false, false, 3);

            w.add(vbox);
            w.show_all(); 
        }
    }       
});


var window = new Example();
Gtk.main();
</pre>

<p>
In the code example, we place two buttons into the right 
bottom corner of the window. To accomplish this, we use 
one horizontal box and one vertical box and one alignment container. 
</p>

<pre class="explanation">
var vbox = new Gtk.VBox({homogeneous: false, spacing:5});
</pre>

<p>
A vertical box container is created. We set the homogeneous member to false. 
This means that widgets put into the vertical box will hot have the same size. 
The vertical spacing between widgets is set to 5 pixels.
</p>

<pre class="explanation">
var space = new Gtk.Frame();
</pre>

<p>
Here we create a Frame widget. The purpose of this widget is to take up
space above the two buttons. 
</p>

<pre class="explanation">
vbox.pack_start(space, true, true, 0);
</pre>

<p>
Here we place the frame widget into the vertical box. The first parameter
of the method is the widget, which is being placed into the box. The following
three parameters are expand, fill and padding. The expand parameter is set to
true, which means that free space will be allocated around the widget. 
When the fill parameter is set to true, the widget actually takes up all
the free space around it. There is no padding around the child widget. 
</p>

<pre class="explanation">
var hbox = new Gtk.HBox({homogeneous: true, spacing:3});            
</pre>

<p>
This code line creates a horizontal box. All widgets inside the
box will have the same size. There will be 3px space between the widgets
horizontally. 
</p>

<pre class="explanation">
var okButton = new Gtk.Button({label:"OK"});
okButton.set_size_request(70, 30);
var closeButton = new Gtk.Button({label:"Close"});

hbox.add(okButton);
hbox.add(closeButton);
</pre>

<p>
We create two buttons and put them inside the horizontal box.
</p>

<pre class="explanation">
var halign = new Gtk.Alignment({xalign: 1.0, yalign: 0.0, 
                                xscale: 0.0, yscale: 0.0});
halign.add(hbox);
vbox.pack_start(halign, false, false, 3);
</pre>

<p>
This will create an alignment container that will place its child widget to the right.
The xalign member set to 1.0 will put all free space to the left of the horizontal box.
This will push the two buttons to the right. We add the horizontal box into the alignment 
container and pack the alignment container
into the vertical box. We must keep in mind that the alignment container 
takes only one child widget. That's why we must use the horizontal box. 
</p>


<img src="/img/gui/jsgtk/buttons.png" alt="Buttons">
<div class="figure">Figure: Buttons</div>


<h2>Calculator skeleton</h2>

<p>
The <b>Table</b> widget arranges widgets in rows and columns. 
</p>

<pre class="code">
#!/usr/bin/seed

/*
ZetCode JavaScript GTK tutorial

In this program we create a skeleton of
a calculator. We use the Table widget.

author: Jan Bodnar
website: www.zetcode.com
last modified: July 2011
*/

Gtk = imports.gi.Gtk;
Gdk = imports.gi.Gdk;

Gtk.init(null, null);

Example = new GType({
    parent: Gtk.Window.type,
    name: "Example",
    init: function ()
    {

        init_ui(this);
      
        function init_ui(w) {  
      
            w.signal.hide.connect(Gtk.main_quit);
            w.set_default_size(300, 250);
            w.set_title("Calculator");
            w.set_position(Gtk.WindowPosition.CENTER);

            var vbox = new Gtk.VBox({homogeneous: false, spacing:2});
            
            var mb = new Gtk.MenuBar();
            var filemenu = new Gtk.Menu();
            var file = new Gtk.MenuItem({label:"File"});
            file.set_submenu(filemenu);
            mb.append(file);

            vbox.pack_start(mb, false, false, 0);

            var table = new Gtk.Table.c_new(5, 4, true);
            
            table.attach_defaults(new Gtk.Button.with_label("Cls"), 0, 1, 0, 1);
            table.attach_defaults(new Gtk.Button.with_label("Bck"), 1, 2, 0, 1);
            table.attach_defaults(new Gtk.Label(), 2, 3, 0, 1);
            table.attach_defaults(new Gtk.Button.with_label("Close"), 3, 4, 0, 1);

            table.attach_defaults(new Gtk.Button.with_label("7"), 0, 1, 1, 2);
            table.attach_defaults(new Gtk.Button.with_label("8"), 1, 2, 1, 2);
            table.attach_defaults(new Gtk.Button.with_label("9"), 2, 3, 1, 2);
            table.attach_defaults(new Gtk.Button.with_label("/"), 3, 4, 1, 2);

            table.attach_defaults(new Gtk.Button.with_label("4"), 0, 1, 2, 3);
            table.attach_defaults(new Gtk.Button.with_label("5"), 1, 2, 2, 3);
            table.attach_defaults(new Gtk.Button.with_label("6"), 2, 3, 2, 3);
            table.attach_defaults(new Gtk.Button.with_label("*"), 3, 4, 2, 3);

            table.attach_defaults(new Gtk.Button.with_label("1"), 0, 1, 3, 4);
            table.attach_defaults(new Gtk.Button.with_label("2"), 1, 2, 3, 4);
            table.attach_defaults(new Gtk.Button.with_label("3"), 2, 3, 3, 4);
            table.attach_defaults(new Gtk.Button.with_label("-"), 3, 4, 3, 4);

            table.attach_defaults(new Gtk.Button.with_label("0"), 0, 1, 4, 5);
            table.attach_defaults(new Gtk.Button.with_label("."), 1, 2, 4, 5);
            table.attach_defaults(new Gtk.Button.with_label("="), 2, 3, 4, 5);
            table.attach_defaults(new Gtk.Button.with_label("+"), 3, 4, 4, 5);

            vbox.pack_start(new Gtk.Entry(), false, false, 0);            
            vbox.pack_end(table, true, true, 0);            
            
            w.add(vbox);
            w.show_all(); 
        }
    }   
    
});

var window = new Example();
Gtk.main();
</pre>

<p>
We use the <b>Table</b> widget to create a calculator skeleton.
</p>


<pre class="explanation">
var table = new Gtk.Table.c_new(5, 4, true);
</pre>

<p>
We create a table widget with 5 rows and 4 columns. The third parameter
is the homogenous parameter. If set to true, all the widgets in the table
are of the same size. The size of all widgets is equal to the largest 
widget in the table container. 
</p>

<pre class="explanation">
table.attach_defaults(new Gtk.Button.with_label("Cls"), 0, 1, 0, 1);
</pre>

<p>
We attach a button to the table container. To the top-left cell of the table. 
The first two parameters are the left and right sides of the cell, the last two
parameters are the top and left sides of the cell. 
</p>

<pre class="explanation">
vbox.pack_end(table, true, true, 0);
</pre>

<p>
We pack the table widget into the vertical box. 
</p>

<img src="/img/gui/jsgtk/calculator.png" alt="Calculator skeleton">
<div class="figure">Figure: Calculator skeleton</div>


<h2>Windows</h2>

<p>
Next we will create a more advanced example. We show a window, 
that can be found in the JDeveloper IDE. 
</p>

<pre class="code">
#!/usr/bin/seed

/*
ZetCode JavaScript GTK tutorial

This is a more complicated layout example.
We use Alignment and Table widgets. 

author: Jan Bodnar
website: www.zetcode.com
last modified: July 2011
*/


Gtk = imports.gi.Gtk;
Gdk = imports.gi.Gdk;


Gtk.init(null, null);

Example = new GType({
    parent: Gtk.Window.type,
    name: "Example",
    init: function ()
    {

        init_ui(this);
      
        function init_ui(w) {

            w.signal.hide.connect(Gtk.main_quit);
            w.set_default_size(300, 280);
            w.set_title("Windows");
            w.set_position(Gtk.WindowPosition.CENTER);

            w.set_border_width(15);
            
            var table = new Gtk.Table.c_new(8, 4, false);
            table.set_col_spacings(3);

            var title = new Gtk.Label.c_new("Windows");

            var halign = new Gtk.Alignment.c_new(0.0, 0.0, 0.0, 0.0);
            halign.add(title);
            
            table.attach(halign, 0, 1, 0, 1, Gtk.AttachOptions.FILL,
                Gtk.AttachOptions.FILL, 0, 0);
                
            var frame = new Gtk.Frame();
            table.attach(frame, 0, 2, 1, 3, Gtk.AttachOptions.FILL | 
                Gtk.AttachOptions.EXPAND, Gtk.AttachOptions.FILL | 
                Gtk.AttachOptions.EXPAND, 1, 1);

            var activate = new Gtk.Button.with_label("Activate");
            activate.set_size_request(50, 30);
            table.attach(activate, 3, 4, 1, 2, Gtk.AttachOptions.FILL,
                Gtk.AttachOptions.SHRINK, 1, 1)
            
            var valign = new Gtk.Alignment.c_new(0.0, 0.0, 0.0, 0.0);
            var closeButton = new Gtk.Button.with_label("Close");
            closeButton.set_size_request(70, 30);
            valign.add(closeButton);
            table.set_row_spacing(1, 3);
            table.attach(valign, 3, 4, 2, 3, Gtk.AttachOptions.FILL,
                Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, 1, 1)
                
            halign2 = new Gtk.Alignment.c_new(0.0, 1.0, 0.0, 0.0);
            help = new Gtk.Button.with_label("Help");
            help.set_size_request(70, 30);
            halign2.add(help);
            table.set_row_spacing(3, 6);
            table.attach(halign2, 0, 1, 4, 5, Gtk.AttachOptions.FILL,
                Gtk.AttachOptions.FILL, 0, 0);
            
            var okButton = new Gtk.Button.with_label("OK");
            okButton.set_size_request(70, 30);
            table.attach(okButton, 3, 4, 4, 5, Gtk.AttachOptions.FILL,
                Gtk.AttachOptions.FILL, 0, 0);
                              
            w.add(table);
            w.show_all(); 
        }
    }       
});


var window = new Example();
Gtk.main();
</pre>

<p>
The code example shows, how we can create a similar window in JavaScript GTK. 
</p>


<pre class="explanation">
var table = new Gtk.Table.c_new(8, 4, false);
table.set_col_spacings(3);
</pre>

<p>
The example is based on the <b>Table</b> container. There will
be 3px space between columns. 
</p>


<pre class="explanation">
var title = new Gtk.Label.c_new("Windows");

var halign = new Gtk.Alignment.c_new(0.0, 0.0, 0.0, 0.0);
halign.add(title);

table.attach(halign, 0, 1, 0, 1, Gtk.AttachOptions.FILL,
    Gtk.AttachOptions.FILL, 0, 0);
</pre>

<p>
This code creates a label, that is aligned to the left. The label 
is placed in the first row of the first column of the Table container.
</p>

<pre class="explanation">
var frame = new Gtk.Frame();
table.attach(frame, 0, 2, 1, 3, Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND,
    Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, 1, 1);
</pre>

<p>
The frame widget spans two rows and two columns. It will consume all free space
around it. Thus, taking the bulk of the area of the window. 
</p>

<pre class="explanation">
var valign = new Gtk.Alignment.c_new(0.0, 0.0, 0.0, 0.0);
var closeButton = new Gtk.Button.with_label("Close");
closeButton.set_size_request(70, 30);
valign.add(closeButton);
table.set_row_spacing(1, 3);
table.attach(valign, 3, 4, 2, 3, Gtk.AttachOptions.FILL,
    Gtk.AttachOptions.FILL | Gtk.AttachOptions.EXPAND, 1, 1)
</pre>

<p>
We put the close button next to the frame widget into the fourth column. 
(we count from zero) We add the button into the alignment widget, 
so that we can align it to the top. 
</p>

<pre class="explanation">
halign2 = new Gtk.Alignment.c_new(0.0, 1.0, 0.0, 0.0);
help = new Gtk.Button.with_label("Help");
help.set_size_request(70, 30);
halign2.add(help);
table.set_row_spacing(3, 6);
table.attach(halign2, 0, 1, 4, 5, Gtk.AttachOptions.FILL,
    Gtk.AttachOptions.FILL, 0, 0);
</pre>

<p>
The help button is placed into the alignment widget, so that it can
be left aligned in its table cell. It is placed at the first column,
fifth row. 
</p>

<pre class="explanation">
var okButton = new Gtk.Button.with_label("OK");
okButton.set_size_request(70, 30);
table.attach(okButton, 3, 4, 4, 5, Gtk.AttachOptions.FILL,
    Gtk.AttachOptions.FILL, 0, 0);
</pre>

<p>
Finally the ok button. It is placed at the fourth column, fifth row.
</p>

<img src="/img/gui/jsgtk/windows.png" alt="Windows">
<div class="figure">Figure: Windows</div>


<p>
In this part of the JavaScript GTK tutorial, we mentioned layout management of widgets. 
</p>

<div class="center"> 
<script type="text/javascript"><!--
google_ad_client = "pub-9706709751191532";
/* horizontal */
google_ad_slot = "1734478269";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script> 
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> 
</script> 
</div> 
<br>


<div class="botNav, center">
<span class="botNavItem"><a href="/">Home</a></span> ‡ <span class="botNavItem"><a href="..">Contents</a></span> ‡ 
<span class="botNavItem"><a href="#">Top of Page</a></span>
</div>


<div class="footer">
<div class="signature">
<a href="/">ZetCode</a> last modified July 30, 2011  <span class="copyright">&copy; 2007 - 2013 Jan Bodnar</span>
</div>
</div>

</div> <!-- content -->

</div> <!-- container -->

</body>
</html>
